home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / protocol / standard / network / utf / utf_fss.c < prev    next >
Text File  |  1993-07-14  |  7KB  |  207 lines

  1.  
  2. /*
  3.  * The following was provided by Ken Thompson of AT&T Bell Laboratories,
  4.  * <ken@research.att.com>, on Tue, 8 Sep 92 03:22:07 EDT, to the X/Open
  5.  * Joint Internationalization Group.  Some minor formatting changes have
  6.  * been made by Glenn Adams, <glenn@metis.com>.
  7.  *
  8.  * -------------------------------------------------------------------------
  9.  *  File System Safe Universal Character Set Transformation Format (FSS-UTF)
  10.  * -------------------------------------------------------------------------
  11.  *
  12.  * With the approval of ISO/IEC 10646 (Unicode) as an international
  13.  * standard and the anticipated wide spread use of this universal coded
  14.  * character set (UCS), it is necessary for historically ASCII based
  15.  * operating systems to devise ways to cope with representation and
  16.  * handling of the large number of characters that are possible to be
  17.  * encoded by this new standard.
  18.  *
  19.  * There are several challenges presented by UCS which must be dealt with
  20.  * by historical operating systems and the C-language programming
  21.  * environment.  The most significant of these challenges is the encoding
  22.  * scheme used by UCS. More precisely, the challenge is the marrying of
  23.  * the UCS standard with existing programming languages and existing
  24.  * operating systems and utilities.
  25.  *
  26.  * The challenges of the programming languages and the UCS standard are
  27.  * being dealt with by other activities in the industry.  However, we are
  28.  * still faced with the handling of UCS by historical operating systems
  29.  * and utilities.  Prominent among the operating system UCS handling
  30.  * concerns is the representation of the data within the file system.  An
  31.  * underlying assumption is that there is an absolute requirement to
  32.  * maintain the existing operating system software investment while at
  33.  * the same time taking advantage of the use the large number of
  34.  * characters provided by the UCS.
  35.  *
  36.  * UCS provides the capability to encode multi-lingual text within a
  37.  * single coded character set.  However, UCS and its UTF variant do not
  38.  * protect null bytes and/or the ASCII slash ("/") making these character
  39.  * encodings incompatible with existing Unix implementations.  The
  40.  * following proposal provides a Unix compatible transformation format of
  41.  * UCS such that Unix systems can support multi-lingual text in a single
  42.  * encoding.  This transformation format encoding is intended to be used
  43.  * as a file code.  This transformation format encoding of UCS is
  44.  * intended as an intermediate step towards full UCS support.  However,
  45.  * since nearly all Unix implementations face the same obstacles in
  46.  * supporting UCS, this proposal is intended to provide a common and
  47.  * compatible encoding during this transition stage.
  48.  *
  49.  * Goal/Objective
  50.  * --------------
  51.  *
  52.  * With the assumption that most, if not all, of the issues surrounding
  53.  * the handling and storing of UCS in historical operating system file
  54.  * systems are understood, the objective is to define a UCS
  55.  * transformation format which also meets the requirement of being usable
  56.  * on a historical operating system file system in a non-disruptive
  57.  * manner.  The intent is that UCS will be the process code for the
  58.  * transformation format, which is usable as a file code.
  59.  *
  60.  * Criteria for the Transformation Format
  61.  * --------------------------------------
  62.  *
  63.  * Below are the guidelines that were used in defining the UCS
  64.  * transformation format:
  65.  *
  66.  *    1) Compatibility with historical file systems:
  67.  *
  68.  *    Historical file systems disallow the null byte and the ASCII
  69.  *    slash character as a part of the file name.
  70.  *
  71.  *    2) Compatibility with existing programs:
  72.  *
  73.  *    The existing model for multibyte processing is that ASCII does
  74.  *    not occur anywhere in a multibyte encoding.  There should be
  75.  *    no ASCII code values for any part of a transformation format
  76.  *    representation of a character that was not in the ASCII
  77.  *    character set in the UCS representation of the character.
  78.  *
  79.  *    3) Ease of conversion from/to UCS.
  80.  *
  81.  *    4) The first byte should indicate the number of bytes to
  82.  *    follow in a multibyte sequence.
  83.  *
  84.  *    5) The transformation format should not be extravagant in
  85.  *    terms of number of bytes used for encoding.
  86.  *
  87.  *    6) It should be possible to find the start of a character
  88.  *    efficiently starting from an arbitrary location in a byte
  89.  *    stream.
  90.  *
  91.  * Proposed FSS-UTF
  92.  * ----------------
  93.  *
  94.  * The proposed UCS transformation format encodes UCS values in the range
  95.  * [0,0x7fffffff] using multibyte characters of lengths 1, 2, 3, 4, 5,
  96.  * and 6 bytes.  For all encodings of more than one byte, the initial
  97.  * byte determines the number of bytes used and the high-order bit in
  98.  * each byte is set.  Every byte that does not start 10xxxxxx is the
  99.  * start of a UCS character sequence.
  100.  *
  101.  * An easy way to remember this transformation format is to note that the
  102.  * number of high-order 1's in the first byte signifies the number of
  103.  * bytes in the multibyte character:
  104.  *
  105.  * Bits  Hex Min  Hex Max  Byte Sequence in Binary
  106.  *   7  00000000 0000007f 0vvvvvvv
  107.  *  11  00000080 000007FF 110vvvvv 10vvvvvv
  108.  *  16  00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv
  109.  *  21  00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
  110.  *  26  00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
  111.  *  31  04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
  112.  *
  113.  * The UCS value is just the concatenation of the v bits in the multibyte
  114.  * encoding.  When there are multiple ways to encode a value, for example
  115.  * UCS 0, only the shortest encoding is legal.
  116.  *
  117.  * Below are sample implementations of the C standard wctomb() and
  118.  * mbtowc() functions which demonstrate the algorithms for converting
  119.  * from UCS to the transformation format and converting from the
  120.  * transformation format to UCS. The sample implementations include error
  121.  * checks, some of which may not be necessary for conformance:
  122.  *
  123.  */
  124.  
  125. typedef struct
  126. {
  127.   int     cmask;
  128.   int     cval;
  129.   int     shift;
  130.   long    lmask;
  131.   long    lval;
  132. } Tab;
  133.  
  134. static Tab tab[] =
  135. {
  136.   0x80,  0x00,   0*6,    0x7F,           0,              /* 1 byte sequence */
  137.   0xE0,  0xC0,   1*6,    0x7FF,          0x80,           /* 2 byte sequence */
  138.   0xF0,  0xE0,   2*6,    0xFFFF,         0x800,          /* 3 byte sequence */
  139.   0xF8,  0xF0,   3*6,    0x1FFFFF,       0x10000,        /* 4 byte sequence */
  140.   0xFC,  0xF8,   4*6,    0x3FFFFFF,      0x200000,       /* 5 byte sequence */
  141.   0xFE,  0xFC,   5*6,    0x7FFFFFFF,     0x4000000,      /* 6 byte sequence */
  142.   0,                                                     /* end of table    */
  143. };
  144.  
  145. int
  146.   mbtowc ( wchar_t *p, char *s, size_t n )
  147. {
  148.   long l;
  149.   int c0, c, nc;
  150.   Tab *t;
  151.   
  152.   if ( s == 0 )
  153.     return 0;
  154.   
  155.   nc = 0;
  156.   if ( n <= nc )
  157.     return -1;
  158.   c0 = *s & 0xff;
  159.   l = c0;
  160.   for ( t = tab; t->cmask; t++ ) {
  161.     nc++;
  162.     if ( ( c0 & t->cmask ) == t->cval ) {
  163.       l &= t->lmask;
  164.       if ( l < t->lval )
  165.     return -1;
  166.       *p = l;
  167.       return nc;
  168.     }
  169.     if ( n <= nc )
  170.       return -1;
  171.     s++;
  172.     c = ( *s ^ 0x80 ) & 0xFF;
  173.     if ( c & 0xC0 )
  174.       return -1;
  175.     l = ( l << 6 ) | c;
  176.   }
  177.   return -1;
  178. }
  179.  
  180. int
  181.   wctomb ( char *s, wchar_t wc )
  182. {
  183.   long l;
  184.   int c, nc;
  185.   Tab *t;
  186.   
  187.   if (s == 0 )
  188.     return 0;
  189.   
  190.   l = wc;
  191.   nc = 0;
  192.   for ( t=tab; t->cmask; t++ ) {
  193.     nc++;
  194.     if ( l <= t->lmask ) {
  195.       c = t->shift;
  196.       *s = t->cval | ( l >> c );
  197.       while ( c > 0 ) {
  198.     c -= 6;
  199.     s++;
  200.     *s = 0x80 | ( ( l >> c ) & 0x3F );
  201.       }
  202.       return nc;
  203.     }
  204.   }
  205.   return -1;
  206. }
  207.